package com.qbw.app.module.vehicle.holder;

import android.content.Context;
import androidx.databinding.BaseObservable;
import androidx.databinding.BindingAdapter;
import androidx.databinding.ViewDataBinding;
import android.graphics.Color;
import android.text.Html;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IFillFormatter;
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.lib.util.DateTimeUtil;
import com.lib.util.ResUtil;
import com.qbw.app.R;
import com.qbw.app.databinding.VehicleHolderStrokeSpeedChartBinding;
import com.qbw.app.manager.UnitManager;
import com.qbw.app.model.TravelGps;
import com.qbw.app.module.common.holder.CommonHolder;
import com.qbw.app.module.common.util.PositionUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @author QBW
 * @date 2019-09-05
 */
public class VehicleTravelSpeedChartHolder extends CommonHolder<VehicleTravelSpeedChartHolder.Data, VehicleHolderStrokeSpeedChartBinding> implements View.OnClickListener {

    public static final int PLAY_STATE_INIT = 1;
    public static final int PLAY_STATE_PLAYING = 2;
    public static final int PLAY_STATE_PAUSE = 3;

    private LineChart mChart;
    private int mPlayState = PLAY_STATE_INIT;
    //private int mTravelProgress;

    public VehicleTravelSpeedChartHolder(Context context, ViewGroup viewParent) {
        super(context, R.layout.vehicle_holder_stroke_speed_chart, viewParent);
        mBinding.lc.setNoDataText("");
    }

    public VehicleTravelSpeedChartHolder(Context context, ViewDataBinding binding) {
        super(context, binding);
        mBinding.lc.setNoDataText("");
    }

    @Override
    public void bindData(int position, Data data) {
        super.bindData(position, data);
        if (mData.mForced) {
            mData.mForced = false;
            init();
            int gpsSize = data.gpsSize();
            if (gpsSize > 0) {
                mBinding.sb.setMax(data.gpsSize() - 1);
                setData(data.mTravelGps);
                mBinding.setGps(data.mTravelGps.get(gpsSize - 1));
                if (gpsSize == 1) {
                    mBinding.setStartGps(data.mTravelGps.get(0));
                    mBinding.setEndGps(data.mTravelGps.get(0));
                } else {
                    mBinding.setStartGps(data.mTravelGps.get(gpsSize - 1));
                    mBinding.setEndGps(data.mTravelGps.get(0));
                }
            } else {
                mBinding.sb.setMax(0);
            }
        }

        mBinding.setData(data);
        mBinding.executePendingBindings();
    }

    @Override
    public void onClick(View v) {

    }

    public void onDrawingGps(TravelGps gps) {
        mBinding.setGps(gps);
    }

    /*public void updatePlayUi(boolean end) {
        mIsPlaying = !end;
        mBinding.ivPlay.setImageResource(end ? R.drawable.play : R.drawable.stop);
        if (end) {
            mBinding.setGps(mBinding.getStartGps());
        }
    }*/

    public void setPlayState(int playState) {
        mPlayState = playState;
        mBinding.ivPlay.setImageResource(playState == PLAY_STATE_PLAYING ? R.drawable.stop : R.drawable.play);
        if (playState == PLAY_STATE_INIT) {
            mBinding.setGps(mBinding.getStartGps());
        }
    }

    public int getPlayState() {
        return mPlayState;
    }

    public static class Data extends BaseObservable {
        private boolean mForced = true;

        private List<TravelGps> mTravelGps;

        public Data(List<TravelGps> travelGps) {
            mTravelGps = travelGps;
        }

        public int gpsSize() {
            return mTravelGps == null ? 0 : mTravelGps.size();
        }
    }

    private void init() {
        mChart = mBinding.lc;
        mChart.setNoDataText("");
        mChart.setViewPortOffsets(0, 0, 0, 0);
        //mChart.setBackgroundColor(Color.rgb(104, 241, 175));

        mChart.setNoDataText("");
        // no description text
        Description description = mChart.getDescription();
        description.setEnabled(false);
        description.setText("");
        // enable touch gestures
        mChart.setTouchEnabled(false);

        // enable scaling and dragging
        mChart.setDragEnabled(false);
        mChart.setScaleEnabled(false);

        // if disabled, scaling can be done on x- and y-axis separately
        mChart.setPinchZoom(false);

        mChart.setDrawGridBackground(false);
        mChart.setMaxHighlightDistance(300);

        XAxis x = mChart.getXAxis();
        x.setEnabled(false);

        YAxis y = mChart.getAxisLeft();
        y.setDrawAxisLine(false);
        //y.setTypeface(mTfLight);
        y.setLabelCount(6, false);
        int colorC = Color.parseColor("#4C97F0");
        y.setTextColor(colorC);
        y.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        y.setDrawGridLines(false);
        y.setAxisLineColor(colorC);
        y.setAxisMinimum(0);
        /*int unitType = CommonPreference.getInstance().getUnitType();
        y.setAxisMaximum(unitType == 2 ? PositionUtil.convertKmToMile(150) : 150);
        if(unitType==2) {
            mBinding.tvLl1.setText(String.valueOf((int)PositionUtil.convertKmToMile(30)));
            mBinding.tvLl2.setText(String.valueOf((int)PositionUtil.convertKmToMile(60)));
            mBinding.tvLl3.setText(String.valueOf((int)PositionUtil.convertKmToMile(90)));
            mBinding.tvLl4.setText(String.valueOf((int)PositionUtil.convertKmToMile(120)));
            mBinding.tvLl5.setText(">"+String.valueOf((int)PositionUtil.convertKmToMile(150)));
        } else {
            mBinding.tvLl1.setText("30");
            mBinding.tvLl2.setText("60");
            mBinding.tvLl3.setText("90");
            mBinding.tvLl4.setText("120");
            mBinding.tvLl5.setText(">150");
        }*/
        setChartMax(100);

        mChart.getAxisRight().setEnabled(false);

        // add data
        //setData(5, 100);

        mChart.getLegend().setEnabled(false);

        //mChart.animateXY(2000, 2000);

        // dont forget to refresh the drawing
        mChart.invalidate();
    }

    private void setChartMax(int max) {
        YAxis y = mChart.getAxisLeft();
        //int unitType = CommonPreference.getInstance().getUnitType();
        //int unitType = 1;
        boolean useKm = UnitManager.getInstance().isUseKm();
        y.setAxisMaximum(!useKm ? (float) PositionUtil.convertKmToMile(max) : max);
        int per = max / 5;
        if (!useKm) {
            mBinding.tvLl1.setText(String.valueOf((int) PositionUtil.convertKmToMile(per)));
            mBinding.tvLl2.setText(String.valueOf((int) PositionUtil.convertKmToMile(per * 2)));
            mBinding.tvLl3.setText(String.valueOf((int) PositionUtil.convertKmToMile(per * 3)));
            mBinding.tvLl4.setText(String.valueOf((int) PositionUtil.convertKmToMile(per * 4)));
            mBinding.tvLl5.setText(String.valueOf((int) PositionUtil.convertKmToMile(per * 5)));
        } else {
            mBinding.tvLl1.setText(String.valueOf(per));
            mBinding.tvLl2.setText(String.valueOf(per * 2));
            mBinding.tvLl3.setText(String.valueOf(per * 3));
            mBinding.tvLl4.setText(String.valueOf(per * 4));
            mBinding.tvLl5.setText(String.valueOf(per * 5));
        }
    }

    public void updateData(int progress) {
        /*if (mData == null) {
            return;
        }
        mTravelProgress = progress;
        mBinding.setGps(mData.mTravelGps.get(mData.gpsSize() - mTravelProgress));
        mBinding.sb.setProgress(mTravelProgress);
        setData(mData.mTravelGps);*/
        if (mData == null) {
            return;
        }
        if (progress < 0 || progress >= mData.gpsSize()) {
            return;
        }
        mBinding.sb.setProgress(progress);
        mBinding.setGps(mData.mTravelGps.get(mData.gpsSize() - 1 - progress));
    }

    private void setData(List<TravelGps> gps) {
        mChart.clear();
        int realGpsSize = gps == null ? 0 : gps.size();
        if (realGpsSize <= 0) {
            return;
        }
        /*int seekProgress = mTravelProgress;
        if (seekProgress == 0) {
            return;
        }
        gps = gps.subList(realGpsSize - seekProgress, realGpsSize);*/
        ArrayList<Entry> yVals = new ArrayList<Entry>();
        float maxSpeed = 0f;

        int x = 0;
        //int unitType = CommonPreference.getInstance().getUnitType();
        int unitType = 1;
        for (int i = gps.size() - 1; i >= 0; i--) {
            //float mult = (range + 1);
            //float val = (float) (Math.random() * mult) + 20;// + (float)
            // ((mult *
            // 0.1) / 10);
            float val = (float) gps.get(i).getGpsSpeed();
            if (val > maxSpeed) {
                maxSpeed = val;
            } else if (val < 0) {
                continue;
            }

            if (unitType == 2) {
                val = (float) PositionUtil.convertKmToMile(val);
            }
            yVals.add(new Entry(x++, val));
        }

        if (yVals.isEmpty()) {
            return;
        }

        if (maxSpeed > 100) {
            if (maxSpeed <= 150) {
                setChartMax(150);
            } else if (maxSpeed > 150 && maxSpeed <= 200) {
                setChartMax(200);
            } else {
                setChartMax((int) maxSpeed);
            }
        }

        LineDataSet set1;

        if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0) {
            set1 = (LineDataSet) mChart.getData().getDataSetByIndex(0);
            set1.setValues(yVals);
            mChart.getData().notifyDataChanged();
            mChart.notifyDataSetChanged();
        } else {
            // create a dataset and give it a type
            set1 = new LineDataSet(yVals, "DataSet 1");

            set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
            set1.setCubicIntensity(0.2f);
            set1.setDrawFilled(true);
            set1.setDrawCircles(false);
            set1.setLineWidth(2.0f);
            set1.setCircleRadius(4f);
            set1.setCircleColor(Color.WHITE);
            //set1.setHighLightColor(Color.parseColor("#aa0000"));
            set1.setColor(Color.parseColor("#b24C97F0"));
            set1.setFillColor(Color.parseColor("#314d6f"));
            set1.setFillAlpha(100);
            set1.setDrawHorizontalHighlightIndicator(false);
            set1.setFillFormatter(new IFillFormatter() {
                @Override
                public float getFillLinePosition(ILineDataSet dataSet,
                                                 LineDataProvider dataProvider) {
                    return 0;
                }
            });

            // create a data object with the datasets
            LineData data = new LineData(set1);
            //data.setValueTypeface(mTfLight);
            data.setValueTextSize(9f);
            data.setDrawValues(false);

            // set data
            mChart.setData(data);
            mChart.post(new Runnable() {
                @Override
                public void run() {
                    //mChart.getData().notifyDataChanged();
                    //mChart.notifyDataSetChanged();
                    mChart.invalidate();
                }
            });
        }
    }

    @BindingAdapter("vehicleSpeedChartCurrentGpsTime")
    public static void setVehicleSpeedChartCurrentGpsTime(TextView textView, long timestamp) {
        textView.setText(Html.fromHtml(String.format(ResUtil.getString(R.string.stroke_time_format),
                                                     timestamp > 0 ? DateTimeUtil.formatHHMM(
                                                             timestamp) : "--")));
    }

    @BindingAdapter("vehicleSpeedChartGpsTime")
    public static void setVehicleSpeedChartGpsTime(TextView textView, long timestamp) {
        if (timestamp <= 0) {
            textView.setText(R.string.na);
            return;
        }
        boolean thisYear = DateTimeUtil.isTimeInThisYear(timestamp);
        textView.setText(thisYear ? DateTimeUtil.formatMMDDHHMM(timestamp) : DateTimeUtil.formatYYYYMMDDHHMM(
                timestamp));
    }
}
